home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d13 / ptv2n1.arc / WATCH.PAS < prev    next >
Pascal/Delphi Source File  |  1991-03-26  |  14KB  |  499 lines

  1. Unit Watch;
  2.  
  3.   { This unit provides watch variable capabilities to object-oriented
  4.     Turbo Pascal programs.
  5.  
  6.     Written by Rick Gessner, 1990.  }
  7.  
  8. Interface {-----------------------------------------------------}
  9.  
  10.   Const MaxListItems = 10;
  11.   Type
  12.     StringPtr = ^String;
  13.     FormatSet = Set of (AsRecord,AsDefault);
  14.  
  15.     PointPtr = ^Point;
  16.     Point = Object
  17.       X,Y     : Integer;
  18.       CONSTRUCTOR Init(Xpos,Ypos: Integer);
  19.       DESTRUCTOR  Done;
  20.       PROCEDURE   MoveTo(NewX,NewY: Integer);
  21.       FUNCTION    WhereXPos: Integer;
  22.       FUNCTION    WhereYPos: Integer;
  23.       PROCEDURE   Show; Virtual;
  24.       FUNCTION    Who_Am_I: StringPtr; Virtual;
  25.       FUNCTION    Describe( FNum: Integer;
  26.                             As: FormatSet): String; Virtual;
  27.       FUNCTION    Find_Var( Identifier: String;
  28.                             Var FNum: Integer): PointPtr; Virtual;
  29.     end; {Point}
  30.  
  31.     Square = Object(Point)
  32.       BotRight  : Point;
  33.       CONSTRUCTOR Init(x1,y1,x2,y2: Integer);
  34.       FUNCTION    Width : Integer;
  35.       FUNCTION    Height: Integer;
  36.       DESTRUCTOR  Done;
  37.       PROCEDURE   Show; Virtual;
  38.       FUNCTION    Who_Am_I: StringPtr; Virtual;
  39.       FUNCTION    Describe( FNum: Integer;
  40.                             As: FormatSet): String; Virtual;
  41.       FUNCTION    Find_Var( Identifier: String;
  42.                             Var FNum: Integer): PointPtr; Virtual;
  43.     end; {Square}
  44.     SquarePtr = ^Square;
  45.  
  46.     TextWindow = Object(Square)
  47.       Heading  :  String;
  48.       CONSTRUCTOR Init(x1,y1,x2,y2: integer; Header: String);
  49.       DESTRUCTOR  Done;
  50.       PROCEDURE   Show; Virtual;
  51.       FUNCTION    Who_Am_I: StringPtr; Virtual;
  52.       FUNCTION    Describe( FNum: Integer;
  53.                             As: FormatSet): String; Virtual;
  54.       FUNCTION    Find_Var( Identifier: String;
  55.                             Var FNum: Integer): PointPtr; Virtual;
  56.     end; {TextWindow}
  57.     TextWindowPtr = ^TextWindow;
  58.  
  59.     List = Object(Point)
  60.       ListName :  String;
  61.       Count    :  Integer;
  62.       Elements :  Array[1..MaxListitems] of PointPtr;
  63.       CONSTRUCTOR Init(Name: String);
  64.       DESTRUCTOR  Done;
  65.       FUNCTION    Add_Element(Item: PointPtr): Integer;
  66.       PROCEDURE   Show; Virtual;
  67.       FUNCTION    Who_Am_I: StringPtr; Virtual;
  68.       FUNCTION    Describe( FNum: Integer;
  69.                             As: FormatSet): String; Virtual;
  70.       FUNCTION    Find_Var( Identifier: String;
  71.                             Var FNum: Integer): PointPtr; Virtual;
  72.     end; {List}
  73.     ListPtr = ^List;
  74.  
  75.     WatchPtr= ^Point;
  76.     WatchObj = Object(Point)
  77.       TheVar,
  78.       VarList : PointPtr;
  79.       FieldNum: Integer;
  80.       Format  : FormatSet;
  81.       Spec    : String;
  82.       CONSTRUCTOR Init(Xpos,Ypos: Integer; Vars: PointPtr);
  83.       DESTRUCTOR  Done;
  84.       PROCEDURE   Show; Virtual;
  85.       PROCEDURE   Get_Format_Specifiers(Identifier: String);
  86.       FUNCTION    Describe( FNum: Integer;
  87.                             As: FormatSet): String; Virtual;
  88.       FUNCTION    Find_Var( Identifier: String;
  89.                             Var FNum: Integer): PointPtr; Virtual;
  90.     end; {WatchObj}
  91.  
  92.   Implementation {----------------------------------------------}
  93.  
  94.   Uses Dos,Crt;
  95.  
  96.   Const Pads   : Array[Boolean] of String[1] = ('',',');
  97.         Prefix : Array[Boolean] of String[1] = ('','(');
  98.         Suffix : Array[Boolean] of String[1] = ('',')');
  99.         MaxLists   = 20;
  100.         UnknownIdentifier = -1;
  101.         ConstantOutOfRange = -2;
  102.  
  103.   { Auxillary Routines... }
  104.  
  105.   FUNCTION Get_Next_Word(Var Expr: String): String;
  106.   Var I,Len: Integer;
  107.   Begin
  108.      I:=1; Len:=0; Get_Next_Word := '';
  109.      While (Expr[I] in ['.',' ']) and (I<Length(Expr)) do Inc(I);
  110.      If Expr[I]=' ' then Exit else
  111.      Begin
  112.        Case Upcase(Expr[i]) of
  113.          '[','-','0'..'9':
  114.             Begin
  115.                If Expr[Len+I]='[' then Inc(I);
  116.                While (I+Len<Length(Expr)) and
  117.                     (Expr[Len+I+1] in ['0'..'9','.','-']) do Inc(Len);
  118.                If Expr[Len+I+1]=']' then Delete(Expr,Len+I+1,1);
  119.             end;
  120.          '#','A'..'Z':
  121.             Begin
  122.                Expr[I+Len]:=UpCase(Expr[I+Len]);
  123.                While (I+Len<Length(Expr)) and
  124.                      (Expr[Len+I+1] in
  125.                       ['#','A'..'Z','a'..'z','0'..'9']) do
  126.                         Begin
  127.                              Inc(Len);
  128.                              Expr[I+Len]:=UpCase(Expr[I+Len]);
  129.                         end; {While}
  130.             end;
  131.             else Exit;
  132.        end; {Case}
  133.        Get_Next_Word := Copy(Expr,I,Len+1);
  134.        Delete(Expr,1,I+Len);
  135.      end; {if}
  136.   end; { Get next word }
  137.  
  138.   FUNCTION Upcase_String(S : String) : String;
  139.   {Function returns the string S, with all uppercase letters.}
  140.   Var StrPos: Integer;
  141.   Begin
  142.      For StrPos:= 1 to Length(S) do S[StrPos]:=Upcase(S[StrPos]);
  143.      Upcase_String:= S;
  144.   end; {UpCase String}
  145.  
  146.  
  147.  { Point Methods: }
  148.  
  149.   CONSTRUCTOR Point.Init(xpos,ypos: integer);
  150.   Begin
  151.      MoveTo(XPos,YPos);
  152.   end; {init}
  153.  
  154.   PROCEDURE Point.MoveTo(NewX,NewY: Integer);
  155.   Begin
  156.      X := NewX; Y:=NewY
  157.   end; {moveto}
  158.  
  159.   FUNCTION Point.WhereXPos: Integer;
  160.   Begin
  161.      WhereXPos := X
  162.   end; {whereXpos}
  163.  
  164.   FUNCTION Point.WhereYPos: Integer;
  165.   Begin
  166.      WhereYPos := Y
  167.   end; {WhereYPos}
  168.  
  169.   DESTRUCTOR Point.Done;
  170.   Begin
  171.      {abstract}
  172.   end; {done}
  173.  
  174.   PROCEDURE Point.Show;
  175.   Begin
  176.      {abstract}
  177.   end; {show}
  178.  
  179.   FUNCTION Point.Who_Am_I: StringPtr;
  180.   Begin
  181.      Who_Am_i:=Nil;
  182.   end; {Who am I}
  183.  
  184.   FUNCTION Point.Describe(FNum: Integer; As: FormatSet): String;
  185.   Const FNames : Array[Boolean,1..2] of String[3] =
  186.                     (('',''),('X:','Y:'));
  187.   Var S,S1: String;
  188.       Stop,Num : Integer;
  189.   Begin
  190.      S:=Prefix[FNum=0];
  191.      If Fnum>2 then Dec(FNum,2);
  192.      If FNum=0 then Stop:=2 else Stop:=Fnum;
  193.      For Num:=FNum to Stop do
  194.         Case Num of
  195.            1 : Begin
  196.                   Str(WhereXPos,S1);
  197.                   S:=S+FNames[As=[AsRecord],Num]+S1+
  198.                      Pads[(Fnum<>Stop) and (Num<>Stop)];
  199.                end;
  200.            2 : Begin
  201.                   Str(WhereYPos,S1);
  202.                   S:=S+Fnames[As=[AsRecord],Num]+S1+
  203.                      Pads[(Fnum<>Stop) and (Num<>Stop)];
  204.                end;
  205.         end; {case}
  206.        Describe:=S+Suffix[FNum=0];
  207.   end; {describe}
  208.  
  209.   FUNCTION Point.Find_Var( Identifier: String;
  210.                            Var FNum: Integer): PointPtr;
  211.   Const  FieldCount = 2;
  212.          FieldNames : Array[1..FieldCount] of String[1] = ('X','Y');
  213.   Var    FieldNum : Integer;
  214.          NextWord : String;
  215.   Begin
  216.      NextWord:=Get_next_Word(Identifier);
  217.      Find_Var:=@Self;
  218.      FieldNum:=0;
  219.      Repeat
  220.            Inc(FieldNum)
  221.      Until (FieldNames[FieldNum]=NextWord) or (FieldNum=FieldCount);
  222.      If FieldNames[FieldNum]=NextWord then FNum:=FieldNum else
  223.         If NextWord<>'' then Find_Var:=Nil;
  224.   end; {find var}
  225.  
  226.   { Square Methods: }
  227.  
  228.   CONSTRUCTOR Square.Init(X1,Y1,X2,Y2: integer);
  229.   Begin
  230.      Point.Init(X1,Y1);
  231.      BotRight.Init(X2,Y2);
  232.   end; {init}
  233.  
  234.   DESTRUCTOR Square.Done;
  235.   Begin
  236.      Point.Done;
  237.      BotRight.Done;
  238.   end; {done}
  239.  
  240.   FUNCTION Square.Width : Integer;
  241.   Begin
  242.      Width := BotRight.WhereXPos-WhereXPos;
  243.   end; {width}
  244.  
  245.   FUNCTION Square.Height: Integer;
  246.   Begin
  247.      Height := BotRight.WhereYPos-WhereYPos;
  248.   end; {Height}
  249.  
  250.   PROCEDURE Square.Show;
  251.   Type   BoxPos = (TopL,TopR,BotL,BotR,Top,Bot,LSide,RSide);
  252.   Const  Boxchar: Array[TopL..RSide] of char =
  253.                     ('┌','┐','└','┘','─','─','│','│');
  254.   Var    I      : Integer;
  255.          S      : String;
  256.   Begin
  257.      Window(WhereXPos,WhereYPos,WhereXPos+Width,WhereYPos+Height);
  258.      ClrScr;
  259.      Write(BoxChar[TopL]);                       {Top left corner}
  260.      For I:=1 to Width-1 do Write(BoxChar[Top]); {Top of square}
  261.      Write(BoxChar[TopR]);                       {Top right corner}
  262.      For I:=2 to Height do  {Draw middle lines}
  263.      Begin
  264.         GotoXY(1,I);
  265.         Write(BoxChar[LSide]);
  266.         GotoXY(Width+1,I);
  267.         Write(BoxChar[RSide]);
  268.      end;
  269.      GotoXY(1,Height+1);
  270.      Write(BoxChar[BotL]);
  271.      For I:=1 to Width-1 do Write(BoxChar[Bot]); {Square bottom}
  272.      Window(1,1,80,25);
  273.      Gotoxy(whereXPos+Width,WhereYPos+Height);
  274.      Write(BoxChar[BotR]);
  275.   end; {show}
  276.  
  277.   FUNCTION Square.Who_Am_I: StringPtr;
  278.   Begin
  279.      Who_Am_I:=Nil;
  280.   end; {Who am I}
  281.  
  282.   FUNCTION Square.Describe(FNum: Integer; As: FormatSet): String;
  283.   Const FName : Array[Boolean] of String[10] = ('','BOTRIGHT:');
  284.   Var S : String;
  285.   Begin
  286.      S:=Prefix[FNum=0];
  287.      If FNum<3 then S:=S+Point.Describe(FNum,As)+Pads[Fnum=0];
  288.      If FNum in [0,3,4] then
  289.         S:=S+FName[As=[AsRecord]]+BotRight.Describe(FNum,As);
  290.      Describe:=S+Suffix[FNum=0];
  291.   end; {describe}
  292.  
  293.   FUNCTION Square.Find_Var( Identifier: String;
  294.                             Var FNum: Integer): PointPtr;
  295.   Var  FieldNum : Integer;
  296.        NextWord : String;
  297.   Begin
  298.      NextWord:=Get_next_Word(Identifier);
  299.      Find_Var:=@Self;
  300.      If NextWord = 'BOTRIGHT' then
  301.         Find_Var:=BotRight.Find_Var(Identifier,FNum) else
  302.         Find_Var:=Point.Find_Var(NextWord+Identifier,FNum);
  303.   end; {find var}
  304.  
  305.   { TextWindow Methods: }
  306.  
  307.   CONSTRUCTOR TextWindow.Init(X1,Y1,X2,Y2: Integer; Header: String);
  308.   Begin
  309.      Square.Init(X1,Y1,X2,Y2);
  310.      Heading:=Header;
  311.   end; {init}
  312.  
  313.   DESTRUCTOR TextWindow.Done;
  314.   Begin
  315.      Square.Done;
  316.   end; {done}
  317.  
  318.   PROCEDURE TextWindow.Show;
  319.   Var I,X1 : Integer;
  320.   Begin
  321.      Square.Show;
  322.      X1 := (Width div 2) - (Length(Heading) div 2);
  323.      Gotoxy(WhereXPos+x1-1,WhereYPos); Write(' ',Heading,' ');
  324.      For I:=1 to 5 do
  325.      Begin
  326.         Gotoxy(WhereXPos+2,WHereYPos+Succ(i));
  327.         Write(Describe(I,[AsRecord]));
  328.      end;
  329.   end; {show}
  330.  
  331.   FUNCTION TextWindow.Who_Am_I: StringPtr;
  332.   Begin
  333.      Who_Am_I:=@Heading;
  334.   end; {Who am I}
  335.  
  336.   FUNCTION TextWindow.Describe(FNum: Integer; As: FormatSet): String;
  337.   Const Quote = Chr(39);
  338.         FName : Array[Boolean] of String[10] = ('','HEADING:');
  339.   Var S: String;
  340.   Begin
  341.      S:='';
  342.      S:=S+Square.Describe(FNum,As);
  343.      If (FNum=0) or (FNum=5) then
  344.      Begin
  345.         If Fnum=0 then S[Length(S)]:=',';
  346.         S:=S+Fname[As=[AsRecord]]+Quote+Heading+Quote;
  347.      end;
  348.      Describe:=s+Suffix[FNum=0];
  349.   end; {describe}
  350.  
  351.   FUNCTION TextWindow.Find_Var( Identifier: String;
  352.                                 Var FNum: Integer): PointPtr;
  353.   Var FieldNum : Integer;
  354.       NextWord : String;
  355.   Begin
  356.      NextWord:=Get_next_Word(Identifier);
  357.      Find_Var:=@Self;
  358.      If NextWord = 'HEADING' then FNum:=5 else
  359.         Find_Var:=Square.Find_Var(NextWord+Identifier,FNum)
  360.   end; {find var}
  361.  
  362.   { List Methods: }
  363.  
  364.   CONSTRUCTOR List.Init( Name: String);
  365.   Begin
  366.      ListName:=Name;
  367.      Count   :=0;
  368.   end; {init}
  369.  
  370.   DESTRUCTOR List.Done;
  371.   Begin
  372.      Point.Done;
  373.   end; {done}
  374.  
  375.   FUNCTION List.Add_Element(Item: PointPtr): Integer;
  376.   Begin
  377.      If Count<MaxListItems then
  378.      Begin
  379.         Inc(Count);
  380.         Elements[count]:=Item;
  381.      end else Add_element:=0;
  382.   end; {Add element}
  383.  
  384.   PROCEDURE List.Show;
  385.   Begin
  386.      {abstract}
  387.   end; {show}
  388.  
  389.   FUNCTION List.Who_Am_I: StringPtr;
  390.   Begin
  391.      Who_Am_I:=@ListName;
  392.   end; {Who am I}
  393.  
  394.   FUNCTION List.Describe(FNum: Integer; As: FormatSet): String;
  395.   Var S,S1: String;
  396.       Start,
  397.       Stop,Num : Integer;
  398.   Begin
  399.      S:=Prefix[Fnum=0];
  400.      If FNum=0 then Stop:=2 else Stop:=Fnum;
  401.      For Num:=Start to Stop do
  402.      Begin
  403.         Case Num of
  404.            1 : Begin
  405.                   S1:=ListName;
  406.                   If As=[AsRecord] then S1:='NAME:'+S1;
  407.                end;
  408.            2 : Str(Count,S1);
  409.         end; {case}
  410.         S:=S+S1+Pads[(Fnum<>0) and (Num<>Stop)];
  411.      end;
  412.      Describe:=S+Suffix[Fnum=0];
  413.   end; {describe}
  414.  
  415.   FUNCTION List.Find_Var( Identifier: String;
  416.                           Var FNum: Integer): PointPtr;
  417.   Var  StrPtr      : StringPtr;
  418.        NextWord    : String;
  419.        APoint      : PointPtr;
  420.        Listelement : integer;
  421.   Begin
  422.      Find_Var:=Nil;
  423.      NextWord  := Get_Next_Word(Identifier);
  424.      For ListElement:=1 to Count do
  425.      Begin
  426.         StrPtr := Elements[ListElement]^.Who_Am_I;
  427.     If (StrPtr<>Nil) and (UpCase_String(StrPtr^)=NextWord) then
  428.     Begin
  429.            APoint:=Elements[ListElement];
  430.            If (Identifier<>'') then
  431.                 Find_Var:=APoint^.Find_Var(Identifier,FNum)
  432.            else Find_Var:=APoint;
  433.         end;
  434.      end
  435.   end; {find var}
  436.  
  437.   { WatchObj Methods: }
  438.  
  439.   CONSTRUCTOR WatchObj.Init(Xpos,Ypos: Integer; Vars: PointPtr);
  440.   Begin
  441.      Point.Init(XPos,YPos);
  442.      VarList:=Vars;
  443.      TheVar :=Nil;
  444.      Spec   :='';
  445.   end; {init}
  446.  
  447.   DESTRUCTOR WatchObj.Done;
  448.   Begin
  449.      Point.Done
  450.   end; {Done}
  451.  
  452.   FUNCTION WatchObj.Describe(FNum: Integer; As: FormatSet): String;
  453.   Begin
  454.      Describe:=TheVar^.Describe(FNum,As);
  455.   end; { Describe }
  456.  
  457.   PROCEDURE WatchObj.Show;
  458.   Var S : String;
  459.   Begin
  460.      If TheVar<>Nil then
  461.           S:=Spec+': '+Describe(FieldNum,Format)
  462.      else
  463.           If SPec<>'' then
  464.                S:=Spec+': Unknown identifier'
  465.           else S:='';
  466.      Gotoxy(WhereXPos,WhereYPos); ClrEol;
  467.      Write(S);
  468.   end; {Show}
  469.  
  470.  PROCEDURE WatchObj.Get_Format_Specifiers(Identifier: String);
  471.  Var I : Integer;
  472.      FormatStr: String;
  473.  Begin
  474.     I:=Pos(',',Identifier);
  475.     Format:=[AsDefault];
  476.     If I<>0 then
  477.     Begin
  478.        FormatStr:=Copy(Identifier,I+1,Length(Identifier));
  479.        Delete(Identifier,I,Length(Identifier));
  480.        If (Pos('r',FormatStr)<>0) or (Pos('R',FormatStr)<>0) then
  481.           Format:=[AsRecord];
  482.     end;
  483.  end; {Get format specifiers}
  484.  
  485. FUNCTION WatchObj.Find_Var( Identifier: String;
  486.                             Var FNum: Integer): PointPtr;
  487. Begin
  488.    TheVar:=Nil;
  489.    FNum:=0;
  490.    Get_Format_Specifiers(Identifier);
  491.    Spec:=Identifier;
  492.    If (VarList<>Nil) and (Identifier<>'') then
  493.    Begin
  494.       TheVar:=VarList^.Find_Var(Identifier,FNum);
  495.       If TheVar<>Nil then FieldNum:=FNum;
  496.    end;
  497. end; {Find Var}
  498.  
  499. end. {Watch Unit}